// Only one of the following 4 symbol be uncomment at any one time
#define V1
//#define V2a
//#define V2b
//#define V2c


///////////////////////////////////////////////////////////////////////


using System;


///////////////////////////////////////////////////////////////////////


public sealed class Program {
	public static void Main() {
		CompanyB.BetterPhone phone = new CompanyB.BetterPhone();
		phone.Dial();
	}
}


///////////////////////////////////////////////////////////////////////



#if V1
namespace CompanyA {
	public class Phone {
		public void Dial() {
			Console.WriteLine("Phone.Dial");
			// Do work to dial the phone here.
		}
	}
}


namespace CompanyB {
	public class BetterPhone : CompanyA.Phone {

		// This Dial method has nothing to do with Phone's Dial method
		new public void Dial() { 
			Console.WriteLine("BetterPhone.Dial");
			EstablishConnection();
			base.Dial();
		}

		protected virtual void EstablishConnection() {
			Console.WriteLine("BetterPhone.EstablishConnection");
			// Do work to establish the connection.
		}
	}
}
#endif


///////////////////////////////////////////////////////////////////////


#if V2a || V2b || V2c
namespace CompanyA {
	public class Phone {
		public void Dial() {
			Console.WriteLine("Phone.Dial");
			EstablishConnection();
			// Do work to dial the phone here.
		}

		protected virtual void EstablishConnection() {
	      Console.WriteLine("Phone.EstablishConnection");
		   // Do work to establish the connection.
		}
	}
}
#endif


///////////////////////////////////////////////////////////////////////


#if V2a
namespace CompanyB {
	public class BetterPhone : CompanyA.Phone {

		// Keep 'new' to mark this method as having no
		// relationship to the base type's Dial method.
		new public void Dial() { 
			Console.WriteLine("BetterPhone.Dial");
			EstablishConnection();
			base.Dial();
		}

		// Add 'new' to mark this method as having no
		// relationship to the base type's EstablishConnection method.
		new protected virtual void EstablishConnection() {
			Console.WriteLine("BetterPhone.EstablishConnection");
			// Do work to establish the connection.
		}
	}
}
#endif


#if V2b
namespace CompanyB {
	public class BetterPhone : CompanyA.Phone {
		// Delete our Dial method (inherit Dial from base)

		// Remove 'new' and change 'virtual' to 'override' to
		// mark this method as having a relationship to the base
		protected override void EstablishConnection() {
			Console.WriteLine("BetterPhone.EstablishConnection");
			// Do work to establish the connection.
		}
	}
}
#endif


#if V2c
namespace CompanyB {
	public class BetterPhone : CompanyA.Phone {

		// Keep 'new' to mark this method as having no
		// relationship to the base type's Dial method.
		new public void Dial() { 
			Console.WriteLine("BetterPhone.Dial");
			EstablishConnection();
			base.Dial();
		}

		// Remove 'new' and change 'virtual' to 'override' to
		// mark this method as having a relationship to the base
		protected override void EstablishConnection() {
			Console.WriteLine("BetterPhone.EstablishConnection");
			// Do work to establish the connection.
		}
	}
}
#endif